import type { ParameterizedContext, Next } from "koa"
import { Model } from "mongoose"
import APIFeatures from "../class/APIFeatures.js"

export const createOne = (Model: Model<any>) => {
  return async (ctx: ParameterizedContext, next: Next) => {
    const type = ctx.request.body
    // @ts-ignore
    if (type === "object" && Object.keys(ctx.request.body as Object).length === 0) {
      ctx.throw(404, "This is a bad request!")
    }
    if (type === "array" && (ctx.request.body as object[]).length === 0) {
      ctx.throw(404, "This is a bad request!")
    }
    const doc = await Model.create(ctx.request.body);
    ctx.status = 200;
    ctx.body = {
      status: "success",
      data: { data: doc }
    }
  }
}

export const deleteOne = (Model: Model<any>) => {
  return async (ctx: ParameterizedContext, next: Next) => {
    const doc = await Model.findByIdAndUpdate(ctx.params.id, { isDelete: true });
    // 查询不到值
    if (!doc) {
      ctx.throw(404, 'No document found with that ID')
    }
    ctx.status = 204;
    ctx.body = {
      status: 'success',
      data: null
    }
  }
}

export const UpdateOne = (Model: Model<any>) => {
  return async (ctx: ParameterizedContext, next: Next) => {
    const doc = await Model.findByIdAndUpdate(ctx.params.id, ctx.request.body as Object, {
      new: true, // 将更新的文档返回出来
      runValidators: true // 根据模型验证数据类型，不添加会导致验证器如 maxlength 等不会触发
    });
    // 查询不到值
    if (!doc) {
      ctx.throw(404, 'No document found with that ID')
    }
    ctx.status = 200;
    ctx.body = {
      status: 'success',
      data: { data: doc }
    }
  }
}

export const getOne = (Model: Model<any>, ...popOptions: any[]) => {
  return async (ctx: ParameterizedContext, next: Next) => {
    // 1 查询值
    let query = Model.findById(ctx.params.id)
    // 2 填充操作
    // @ts-ignore
    if (popOptions) query.populate(...popOptions)
    // 3 隐藏 __v 字段
    query.select('-__v');
    const doc = await query
    if (!doc) {
      ctx.throw(404, 'No document found with that ID')
    }
    ctx.status = 200;
    ctx.body = {
      status: 'success',
      data: { data: doc }
    }
  }
}

export const getAll = (Model: Model<any>) => {
  return async (ctx: ParameterizedContext, next: Next) => {
    // 1 查询
    const features = new APIFeatures(Model.find(), ctx.query);
    features.filter().sort().limitFields().paginate();
    const doc = await features.check;
    // 2 返回值
    ctx.status = 200;
    ctx.body = {
      status: 'success',
      data: {
        results: doc.length,
        data: doc
      }
    }
  }
}


